/* Copyright 2014 InterCommIT b.v. * * This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves * * Weaves is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Weaves is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Weaves. If not, see <http://www.gnu.org/licenses/>. * */ package nl.intercommit.weaves.grid; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.tapestry5.grid.SortConstraint; import org.apache.tapestry5.ioc.internal.util.TapestryException; public class JPAPagedGridDataSource<T> extends PagedGridDataSource<T> { private final EntityManager em; /* * These fields are required later on to filter on fields. */ private CriteriaBuilder cb = null; private Root<T> root = null; private List<Predicate> predicates = null; public JPAPagedGridDataSource(final EntityManager em,final Class<T> entityType) { super(entityType); this.em = em; try { em.getEntityManagerFactory().getMetamodel().managedType(entityType); } catch (IllegalArgumentException e) { throw new TapestryException("This entity ["+entityType+"] is not managed by the given entitymanager", this, e); } } @Override public List<T> fetchResult(int startIndex, int endIndexPlusOne, List<SortConstraint> sortConstraints) { // We just assume that the property names in the SortContraint match the Hibernate // properties. cb = em.getCriteriaBuilder(); final CriteriaQuery<T> cq = cb.createQuery(getRowType()); root = cq.from(getRowType()); // the FROM clause predicates = new ArrayList<Predicate>(); //Constructing list of parameters applyFiltering(); // use the predicates, cb and root fields to fill up the filters final List<String> orderedFields = new ArrayList<String>(); for (final SortConstraint constraint : sortConstraints) { final String propertyName = constraint.getPropertyModel().getPropertyName(); if (!orderedFields.contains(propertyName)) { orderedFields.add(propertyName); switch (constraint.getColumnSort()) { case ASCENDING: cq.orderBy(cb.asc(root.get(propertyName))); break; case DESCENDING: cq.orderBy(cb.desc(root.get(propertyName))); break; default: } } } cq.select(root).where(predicates.toArray(new Predicate[]{})); final TypedQuery<T> q = em.createQuery(cq); q.setFirstResult(startIndex); q.setMaxResults(endIndexPlusOne - startIndex + 1); return q.getResultList(); } @Override public Object getIdentifierForRowValue(final Object rowObject) { try { return em.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(rowObject); } catch (Exception toe) { toe.printStackTrace(); return null; } } @Override public Class<?> getRowIdClass() { return em.getEntityManagerFactory().getMetamodel().entity(getRowType()).getIdType().getJavaType(); } /** * Can be used when the applyFiltering function is called, to add extra filtering. * * @return */ protected List<Predicate> getPredicates() { return predicates; } protected CriteriaBuilder getCb() { return cb; } protected Root<T> getRoot() { return root; } }